/*eslint-env node*/

const fs = require('fs')
const path = require('path')
const semver = require('semver')
const postcss = require('postcss')
const nodeExternals = require('webpack-node-externals')
const ZipWebpackPlugin = require('zip-webpack-plugin')
const _ = require('lodash')
const commonUtils = require('./tools/utils')

/**
 *
 * @param {*} options 具体请看 https://poi.js.org/#/options
 */
module.exports = options => ({
  // entry 是在 src/manifest.json 指定的
  entry: {},
  // 拷贝资源
  copy: [
    {context: 'src', from: '*.*', ignore: ['*.json']},
    {
      context: 'src',
      from: '**/*.json',
      transform(content, filePath) {
        return new Buffer(commonUtils.inlineImageFromJson(content.toString(), path.dirname(filePath), 10000))
      }
    }
  ],
  // 每次构建都先删除 dist 目录
  cleanOutDir: true,
  // 输出 umd 或者 cjs 格式
  format: 'umd',
  // 是否压缩JS和CSS
  minimize: true,
  // 是否分离样式
  css: {
    extract: false
  },
  // 设置是否构建 html
  html: false,
  // css处理
  postcss: {
    plugins: [
      postcss.plugin('postcss-xcube-asset', function(opts = {}) {
        return function(css, result) {
          // 追加前端资产标识，用于设计时
          css.prepend('.xcube-ui-asset:empty { clear: none }')
        }
      })
    ]
  },
  presets: [require('@poi/plugin-bundle-report')(), require('@poi/plugin-webpackmonitor')()],
  // 过滤指定包，不打进包中
  // configureWebpack(config) {
  //   config.externals = {
  //     jquery: {
  //       root: 'jQuery',
  //       commonjs: 'jquery',
  //       commonjs2: 'jquery',
  //       amd: 'jquery'
  //     },
  //     vue: {
  //       root: 'Vue',
  //       commonjs: 'vue',
  //       commonjs2: 'vue',
  //       amd: 'vue'
  //     },
  //     'element-ui': {
  //       root: 'ELEMENT',
  //       commonjs: 'element-ui',
  //       commonjs2: 'element-ui',
  //       amd: 'element-ui'
  //     }
  //   }
  //   return config
  // },

  configureWebpack(config) {
    // config.plugins = config.plugins.filter(removeSomePlugin);
    return config
  },
  // 使用 webpack-chain 方式修改 webpack 配置, https://poi.js.org/#/options?id=extendwebpack
  chainWebpack(config) {
    const manifestPath = path.resolve('./src/manifest.json')
    const manifest = require(manifestPath)
    // 升级版本号
    manifest.version = semver.inc(manifest.version, 'patch')
    fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))

    // 遍历 components 数组
    _.get(manifest, 'package.components', []).forEach(fileName => {
      // 通过文件路径得到目录名
      const dirName = path.dirname(fileName)
      // 读取控件定义文件
      const jsonDef = require(path.resolve(path.join('./src', fileName)))

      let props = [
        'main', // 组件运行态
        'mainDesignTime', // 组件设计态
        'customPanel', // 自定义面板
        'customPropertyEditor' // 属性编辑器
      ]

      props
        // 过滤掉不存在或者值为空的属性
        .filter(file => file in jsonDef && jsonDef[file])
        .map(file => ({
          // webpack entry 名不带后缀
          name: path.posix.join(dirName, jsonDef[file].replace(/\.\w+$/, '')),
          // @/ 开头
          value: path.posix.join('@', dirName, jsonDef[file])
        }))
        // 使用 webpack-chain 添加到 entry
        .forEach(({name, value}) => config.entry(name).add(value))
    })

    const fileLoaderOptions = {
      publicPath: url => `component:${manifest.name}/${manifest.version}/${url}`
    }

    config.module
      .rule('font')
      .test(/\.(eot|otf|webp|ttf|woff|woff2)(\?.*)?$/)
      .use('file-loader')
      .loader(path.resolve(__dirname, 'tools/resource-loader/index'))
      .tap(options => Object.assign(options, fileLoaderOptions))

    // 修改 webpack 常量
    config.plugin('define').tap(args => {
      args[0] = Object.assign(args[0], {
        XCUBE_COMPONENT: JSON.stringify(`component:${manifest.name}/${manifest.version}/`)
      })
      return [...args]
    })

    // 压缩构建目录，名字使用 manifest.json 的 name
    config.plugin('zip').use(ZipWebpackPlugin, [{filename: manifest.name}])

    // 排除掉 node_modules
    // 暂时不能排除，因为第三方资产是使用 SystemJS 加载的，无法访问到 webpack 已构建的模块
    // config.externals(
    //   nodeExternals({
    //     whitelist: [/\.(?!(?:jsx?|json)$).{1,5}$/i]
    //   })
    // );
  }
})
